﻿using BCCommon;
using BCCommon.Enums;
using BCData.Common.News.NewsContent;
using BCData.Common.News.NewsContentComment;
using BCDto.Common.News.NewsContent;
using BCEntity.Common.EntityNameConst;
using BCEntity.Common.News.NewsContent;
using BCService.Utils;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BCService.Common.News.NewsContentService
{
    /// <summary>
    /// 新闻相关服务
    /// </summary>
    public class NewsContentService : INewsContentService
    {
        private readonly IConfiguration configuration;
        private readonly INewsContentData newsContentData;
        private readonly INewsContentCommentData newsContentCommentData;
        private readonly IRedisService redisService;

        private readonly string key = string.Format("{0}", EntityNameConst.NewsContentEntity);

        public NewsContentService(IConfiguration configuration, INewsContentData newsContentData, INewsContentCommentData newsContentCommentData,IRedisService redisService)
        {
            this.configuration = configuration;
            this.newsContentData = newsContentData;
            this.newsContentCommentData = newsContentCommentData;
            this.redisService = redisService;
        }

        public int GetListCount(int? contentCategoryId, string title, string keyWord, DateTime? start, DateTime? end, bool fromSim)
        {
            return this.newsContentData.GetListCount(contentCategoryId, title, keyWord, start, end, fromSim);
        }

        public PageableList<NewsContentDto> GetNewsPagingList(int? contentCategoryId, string title,string keyWord,DateTime? start,DateTime? end, bool fromSim, bool? ascending, int index, int size)
        {
            var list = newsContentData.GetPageableList(contentCategoryId,title,keyWord,start,end, ascending, fromSim, out int dataCount, index, size);

            return new PageableList<NewsContentDto>
            {
                Count = dataCount,
                PageIndex = index,
                PageSize = size,
                Items = list.As<IEnumerable<NewsContentDto>>()
            };
        }

        public IEnumerable<NewsContentDto> GetNewsListByContentCategoryId(int contentCategoryId)
        {
            var list = newsContentData.GetNewsList(contentCategoryId);
            return list.As<IEnumerable<NewsContentDto>>();
        }

        public IEnumerable<NewsContentDto> GetContentListByIndexAndAmount(int contentCategoryId, int startIndex = 0, int amount = 0)
        {
            var list = newsContentData.GetContentListByIndexAndAmount(contentCategoryId,startIndex,amount);
            return list.As<IEnumerable<NewsContentDto>>();
        }

        public IEnumerable<NewsContentDto> GetNewById(long newsContentId)
        {
            var list = newsContentData.GetNewById(newsContentId);
            return list.As<IEnumerable<NewsContentDto>>();
        }

        public PageableList<NewsContentViewDto> GetViewList(int? contentCategoryId, string title, string keyWord, bool fromSim, bool? ascending, int index, int size)
        {
            var list = newsContentData.GetViewPageableList(contentCategoryId, title, keyWord,fromSim, out int dataCount, ascending, index, size);

            return new PageableList<NewsContentViewDto>
            {
                Count = dataCount,
                PageIndex = index,
                PageSize = size,
                Items = list.As<IEnumerable<NewsContentViewDto>>()
            };
        }

        public NewsContentDto Create(NewsContentRequestDto dto, long adminId,string adminName)
        {
            var entity = dto.As<NewsContentEntity>();
            entity.AdminId = adminId;
            entity.AdminName = adminName;
            return this.newsContentData.Add(entity).As<NewsContentDto>();
        }

        public NewsContentDto Update(long newsContentId, NewsContentRequestDto dto,long adminId)
        {
            var entity = dto.As<NewsContentEntity>();
            entity.NewsContentId = newsContentId;
            entity.AdminId = adminId;
            return this.newsContentData.UpdateEntity(entity).As<NewsContentDto>();
        }
        
        public IEnumerable<NewsContentDto> Delete(long newsContentId)
        {
            //如果有评价信息，先删除评价
            var newsContentComments = this.newsContentCommentData.GetNewsContentCommentByNewsContentId(newsContentId);
            if (newsContentComments.Any())
            {
                this.newsContentCommentData.DeleteNewsContentCommentByNewsContentId(newsContentId);
            }
            return this.newsContentData.DeleteEntity(newsContentId).As<IEnumerable<NewsContentDto>>();
        }
        
        public NewsContentDto GetNewsContentById(long newsContentId, bool fromSim)
        {
            return this.newsContentData.GetNewsContentById(newsContentId, fromSim).As<NewsContentDto>();
        }

        public void UpdateViewsCount(long newsContentId)
        {
            this.newsContentData.UpdateViewsCount(newsContentId);
        }
        
        public void UpdateLikeCount(long newsContentId)
        {
            this.newsContentData.UpdateLikeCount(newsContentId);
        }

        public NewsContentDto GetNewsContentByProtocol(string protocolType)
        {
            string cacheKey = this.redisService.GetKey(key, protocolType);
            var entity = this.redisService.TryGet(cacheKey, () => this.newsContentData.GetNewsContentByProtocol(protocolType), TimeSpan.FromMinutes(30));

            return entity.As<NewsContentDto>();
        }
        
        public NewsContentDto UpdateReprintCount(long newsContentId)
        {
            var entities=this.newsContentData.GetNewsContentById(newsContentId, false);
            if (entities==null)
            {
                throw new ArgumentException("该新闻不存在。");
            }
            var result=this.newsContentData.UpdateReprintCount(newsContentId);
            return result.As<NewsContentDto>();
        }

        public PageableList<NewsContentDto> QueryNewsByKeyWord(int? contentCategoryId, string keyWord, int pageIndex = 1, int pageSize = 20)
        {
            var list = newsContentData.QueryNewsByKeyWord(contentCategoryId, keyWord, out int dataCount, pageIndex, pageSize);
            return new PageableList<NewsContentDto>
            {
                Count = dataCount,
                PageIndex = pageIndex,
                PageSize = pageSize,
                Items = list.As<IEnumerable<NewsContentDto>>()
            };
        }


        public NewsContentDto QueryPreviouOrNext(long newsContentId, bool isNext)
        {
            var entity = this.newsContentData.GetNewsContentNextOrPreviou(newsContentId, isNext);
            if (entity.IsNull())
            {
                return null;
            }
            entity.WebSite = configuration["DefaultHost"];
            return entity.As<NewsContentDto>();
        }

        #region 检查新闻内容是否存在
        private bool Exists(long newsContentId)
        {
            return this.newsContentData.Exists(newsContentId).GetAwaiter().GetResult();
        }
        #endregion

        #region 启用新闻内容
        public bool Enabled(long newsContentId)
        {
            if (!this.Exists(newsContentId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var result = this.newsContentData.Enabled(newsContentId).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, newsContentId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 禁用新闻内容
        public bool Disabled(long newsContentId)
        {
            if (!this.Exists(newsContentId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var result = this.newsContentData.Disabled(newsContentId).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, newsContentId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

    }
}
